package com.microframework.boot.system.service.impl;

import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Page;
import com.microframework.base.core.util.SecurityUtils;
import com.microframework.base.core.util.UuidUtil;
import com.microframework.base.web.page.PageQuery;
import com.microframework.base.web.resp.R;
import com.microframework.boot.system.model.domain.Dict;
import com.microframework.boot.system.model.domain.DictItem;
import com.microframework.boot.system.service.IDictService;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class DictServiceImpl implements IDictService {

	@Override
	public Page<Dict> pages(PageQuery<Dict> pageQuery) {
		try {
			StringBuilder sqlBuilder = new StringBuilder("FROM " + Dict.TABLE_NAME + " WHERE 1=1");
			List<Object> params = new ArrayList<>();

			Dict query = pageQuery.getQuery();
			if (query != null) {
				// 构建查询条件

				if (StringUtils.hasText(query.getCnName())) {
					sqlBuilder.append(" AND cn_name LIKE ?");
					params.add("%" + query.getCnName() + "%");
				}
				
				if (StringUtils.hasText(query.getEnName())) {
					sqlBuilder.append(" AND en_name LIKE ?");
					params.add("%" + query.getEnName() + "%");
				}
				
				if (StringUtils.hasText(query.getCode())) {
					sqlBuilder.append(" AND code LIKE ?");
					params.add("%" + query.getCode() + "%");
				}
				
				if (StringUtils.hasText(query.getIsDel())) {
					sqlBuilder.append(" AND is_del = ?");
					params.add(query.getIsDel());
				}else {
					sqlBuilder.append(" AND is_del = ?");
					params.add("0");
				}
			}
			else {
				sqlBuilder.append(" AND is_del = ?");
				params.add("0");
			}
			// 设置排序
			String orderBy = StringUtils.hasText(pageQuery.getOrderBy()) ? pageQuery.getOrderBy() : "sort";
			String orderDirection = StringUtils.hasText(pageQuery.getOrderDirection()) ? pageQuery.getOrderDirection()
					: "asc";
			sqlBuilder.append(" ORDER BY " + orderBy + " " + orderDirection);
			String select="select id,cn_name,en_name,code,remark,sort,create_time,modify_time ";
			
			return Dict.dao.paginate(pageQuery.getPageNumber(), pageQuery.getPageSize(), select,sqlBuilder.toString(), params.toArray());
		} catch (Exception e) {
			log.error("查询字典列表异常{}", e.getMessage());
			return new Page<Dict>(new ArrayList<>(), 1, 10, 0, 0);
		}
	}

	@Override
	public List<DictItem> getItemPages(PageQuery<DictItem> pageQuery) {
		try {
			String select="select * ";
			StringBuilder sqlBuilder = new StringBuilder("FROM " + DictItem.TABLE_NAME + " WHERE 1=1 ");
			List<Object> params = new ArrayList<>();
			DictItem query = pageQuery.getQuery();
			sqlBuilder.append(" AND dict_id = ?");
			params.add(query.getDictId());
			
			if (query != null) {
				// 构建查询条件
				if (StringUtils.hasText(query.getCnLabel())) {
					sqlBuilder.append(" AND cn_label LIKE ?");
					params.add("%" + query.getCnLabel() + "%");
				}
				
				if (StringUtils.hasText(query.getEnLabel())) {
					sqlBuilder.append(" AND en_label LIKE ?");
					params.add("%" + query.getEnLabel() + "%");
				}
				
				if (StringUtils.hasText(query.getStatus())) {
					sqlBuilder.append(" AND status = ?");
					params.add("" + query.getStatus() + "");
				}
				
				if (StringUtils.hasText(query.getIsDel())) {
					sqlBuilder.append(" AND is_del = ?");
					params.add(query.getIsDel());
				}else {
					sqlBuilder.append(" AND is_del = ?");
					params.add("0");
				}
			}
			
			// 设置排序
			String orderBy = StringUtils.hasText(pageQuery.getOrderBy()) ? pageQuery.getOrderBy() : "sort";
			String orderDirection = StringUtils.hasText(pageQuery.getOrderDirection()) ? pageQuery.getOrderDirection()
					: "asc";
			sqlBuilder.append(" ORDER BY " + orderBy + " " + orderDirection);
			
			return DictItem.dao.find( select+sqlBuilder.toString(), params.toArray());
		} catch (Exception e) {
			log.error("查询字典项列表异常{}", e.getMessage());
			return new LinkedList<DictItem>();
		}
	}

    //@CachePut(value = CacheConstants.SYS_DICT_ITEMS, key = "#item.id")
	@Override
	public R<DictItem> save(DictItem item) {
		try {
			if (StrKit.notBlank(item.getId())) {
				DictItem checkDictItem=DictItem.dao.findFirst("select id from "+DictItem.TABLE_NAME+" where dict_id=? and value=? and id!=?",item.getDictId(),item.getValue(),item.getId());
				if(checkDictItem!=null) {
					return R.fail("值重复.");
				}
				item.setModifyTime(new Date(System.currentTimeMillis()));
				item.setModifyUserId(SecurityUtils.getUserId());
				if (item.update()) {
					return R.ok(item);
				} else {
					return R.fail("更新失败.");
				}
			} else {
				DictItem checkDictItem=DictItem.dao.findFirst("select id from "+DictItem.TABLE_NAME+" where dict_id=? and value=? ",item.getDictId(),item.getValue());
				if(checkDictItem!=null) {
					return R.fail("值重复.");
				}
				item.setId(UuidUtil.getUUID());
				item.setCreateTime(new Date(System.currentTimeMillis()));
				item.setCreateUserId(SecurityUtils.getUserId());
				if (item.save()) {
					return R.ok(item);
				} else {
					return R.fail("保存失败.");
				}
			}
		} catch (Exception e) {
			return R.fail(e.getMessage());
		}
	}

    //@CacheEvict(value = CacheConstants.SYS_DICT_ITEMS, key = "#id")
	@Override
	public R<String> deleteItem(String id) {
    	try {
			DictItem dictItem=new DictItem();
			dictItem.setId(id);
			dictItem.setIsDel("1");
			if(dictItem.update()) {
				return R.ok("删除成功.");
			}else {
				return R.fail("删除失败.");
			}
		}catch (Exception e) {
			log.error("删除异常:{}",e.getMessage());
			return R.fail(e.getMessage());
		}
	}

	@Override
	public List<Dict> loadAll(PageQuery<Dict> pageQuery) {
		try {
			String select="select * ";
			StringBuilder sqlBuilder = new StringBuilder(select+" FROM " + Dict.TABLE_NAME + " WHERE 1=1");
			List<Object> params = new ArrayList<>();

			Dict query = pageQuery.getQuery();
			if (query != null) {
				// 构建查询条件

				if (StringUtils.hasText(query.getCnName())) {
					sqlBuilder.append(" AND cn_name LIKE ?");
					params.add("%" + query.getCnName() + "%");
				}
				
				if (StringUtils.hasText(query.getEnName())) {
					sqlBuilder.append(" AND en_name LIKE ?");
					params.add("%" + query.getEnName() + "%");
				}
				
				if (StringUtils.hasText(query.getCode())) {
					sqlBuilder.append(" AND code LIKE ?");
					params.add("%" + query.getCode() + "%");
				}
				
				if (StringUtils.hasText(query.getParentId())) {
					sqlBuilder.append(" AND parent_id = ?");
					params.add(query.getParentId());
				}
				
				if (StringUtils.hasText(query.getIsDel())) {
					sqlBuilder.append(" AND is_del = ?");
					params.add(query.getIsDel());
				}else {
					sqlBuilder.append(" AND is_del = ?");
					params.add("0");
				}
			}

			// 设置排序
			String orderBy = StringUtils.hasText(pageQuery.getOrderBy()) ? pageQuery.getOrderBy() : " sort";
			String orderDirection = StringUtils.hasText(pageQuery.getOrderDirection()) ? pageQuery.getOrderDirection()
					: "desc";
			sqlBuilder.append(" ORDER BY " + orderBy + " " + orderDirection);
			List<Dict> orgs=Dict.dao.find(sqlBuilder.toString(), params.toArray());
			return buildTree(orgs);
		} catch (Exception e) {
			log.error("查询异常{}", e.getMessage());
			return new LinkedList<Dict>();
		}
	}

	@Override
	public List<Dict> loadLazy(PageQuery<Dict> pageQuery) {
		try {
			String select="select m.*,IFNULL((SELECT COUNT(id) FROM "+Dict.TABLE_NAME+" WHERE parent_id = m.id and is_del=0 ), 0) > 0 AS has_children ";
			StringBuilder sqlBuilder = new StringBuilder(select+" FROM " + Dict.TABLE_NAME + " m WHERE 1=1");
			List<Object> params = new ArrayList<>();

			Dict query = pageQuery.getQuery();
			if (query != null) {
				// 构建查询条件

				if (StringUtils.hasText(query.getCnName())) {
					sqlBuilder.append(" AND m.cn_name LIKE ?");
					params.add("%" + query.getCnName() + "%");
				}
				
				if (StringUtils.hasText(query.getEnName())) {
					sqlBuilder.append(" AND m.en_name LIKE ?");
					params.add("%" + query.getEnName() + "%");
				}
				
				if (StringUtils.hasText(query.getCode())) {
					sqlBuilder.append(" AND m.code LIKE ?");
					params.add("%" + query.getCode() + "%");
				}
				
				if (StringUtils.hasText(query.getParentId())) {
					sqlBuilder.append(" AND m.parent_id = ?");
					params.add(query.getParentId());
				}
				
				if (StringUtils.hasText(query.getIsDel())) {
					sqlBuilder.append(" AND m.is_del = ?");
					params.add(query.getIsDel());
				}else {
					sqlBuilder.append(" AND m.is_del = ?");
					params.add("0");
				}
			}

			// 设置排序
			String orderBy = StringUtils.hasText(pageQuery.getOrderBy()) ? "m."+pageQuery.getOrderBy() : " m.sort";
			String orderDirection = StringUtils.hasText(pageQuery.getOrderDirection()) ? pageQuery.getOrderDirection()
					: " asc ";
			sqlBuilder.append(" ORDER BY " + orderBy + " " + orderDirection);
			return Dict.dao.find(sqlBuilder.toString(), params.toArray());
		} catch (Exception e) {
			log.error("查询异常{}", e.getMessage());
			return new LinkedList<Dict>();
		}
	}

	public List<Dict> buildTree(List<Dict> nodes) {
	    // 1. 创建快速查找映射表
	    Map<String, Dict> nodeMap = new HashMap<>();
	    Map<String, List<Dict>> parentChildMap = new HashMap<>();
	    
	    // 2. 构建索引
	    for (Dict node : nodes) {
	        String nodeId = node.getId();
	        String parentId = node.getParentId();
	        
	        // 存储节点映射
	        nodeMap.put(nodeId, node);
	        
	        // 构建父子关系映射
	        parentChildMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(node);
	    }
	    
	    // 3. 识别根节点（没有父节点或父节点不存在）
	    List<Dict> roots = new ArrayList<>();
	    for (Dict node : nodes) {
	        String parentId = node.getParentId();
	        
	        // 根节点条件：父节点为空、不存在或指向自身（根据业务需求调整）
	        if (parentId == null || 
	            !nodeMap.containsKey(parentId) || 
	            parentId.equals(node.getId())) {
	            roots.add(node);
	        }
	    }
	    
	    // 4. 递归构建树形结构
	    roots.forEach(root -> buildTreeRecursive(root, parentChildMap));
	    
	    return roots;
	}

	private void buildTreeRecursive(Dict node, Map<String, List<Dict>> parentChildMap) {
	    String nodeId = node.getId();
	    List<Dict> children = parentChildMap.get(nodeId);
	    
	    if (children != null && !children.isEmpty()) {
	        // 设置子节点并继续递归构建
	        node.setChildren(children);
	        children.forEach(child -> buildTreeRecursive(child, parentChildMap));
	    }
	}

}
